<script setup lang="ts">
import type { Region } from '#/api/system/region/model';

import { computed, ref } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { addFullName, cloneDeep, listToTree } from '@vben/utils';

import { useVbenForm } from '#/adapter/form';
import {
  regionAdd,
  regionInfo,
  regionTreeList,
  regionUpdate,
} from '#/api/system/region';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';

import { drawerSchema } from './data';

const emit = defineEmits<{ reload: [] }>();

interface DrawerProps {
  region?: Region;
  sort?: number;
  update: boolean;
}

const isUpdate = ref(false);
const title = computed(() => {
  return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});

const [BasicForm, formApi] = useVbenForm({
  commonConfig: {
    componentProps: {
      class: 'w-full',
    },
    formItemClass: 'col-span-2',
    labelWidth: 120,
  },
  schema: drawerSchema(),
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2',
});

async function getRegionTree() {
  let ret: Region[] = [];
  ret = await regionTreeList();
  const treeData = listToTree(ret, { id: 'code', pid: 'parentCode' });
  // 添加省市区链路名称 如 xx-xx-xx
  addFullName(treeData, 'name', ' / ');
  return treeData;
}

async function initRegionSelect() {
  // 需要动态更新TreeSelect组件 这里允许为空
  const treeData = await getRegionTree();
  formApi.updateSchema([
    {
      componentProps: {
        fieldNames: { label: 'name', value: 'code' },
        showSearch: true,
        treeData,
        treeDefaultExpandAll: true,
        treeLine: { showLeafIcon: false },
        // 选中后显示在输入框的值
        treeNodeLabelProp: 'fullName',
      },
      fieldName: 'parentCode',
    },
  ]);
}

const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
  {
    initializedGetter: defaultFormValueGetter(formApi),
    currentGetter: defaultFormValueGetter(formApi),
  },
);

const [BasicDrawer, drawerApi] = useVbenDrawer({
  onBeforeClose,
  onClosed: handleClosed,
  onConfirm: handleConfirm,
  async onOpenChange(isOpen) {
    if (!isOpen) {
      return null;
    }
    drawerApi.drawerLoading(true);

    const { region, update, sort } = drawerApi.getData() as DrawerProps;
    isUpdate.value = update;

    if (!update && sort) {
      await formApi.setFieldValue('sort', sort);
    }

    if (region?.code) {
      await formApi.setFieldValue('parentCode', region.code); // 新增时，当前区划作为父区划
      if (update) {
        const record = await regionInfo(region.code);
        await formApi.setValues(record); // 修改时，更新父区划
      } else {
        if (region.level) {
          // 在当前区划新增下级，更新层级
          await formApi.setValues({ level: region.level + 1 });
        }
      }
    } else {
      // 最顶级新增国家，默认父区划为0
      await formApi.setValues({ parentCode: '0', level: 0 });
    }

    // 编辑时禁止修改父区划、父区划编号、区划编号、区划等级
    formApi.updateSchema([
      // {
      //   fieldName: 'parentCode',
      //   componentProps: {
      //     disabled: isUpdate.value,
      //   },
      // },
      {
        fieldName: 'code',
        componentProps: {
          disabled: isUpdate.value,
        },
      },
      {
        fieldName: 'level',
        componentProps: {
          disabled: isUpdate.value,
        },
      },
    ]);

    /** 父区划选择 下拉框 */
    await initRegionSelect();
    await markInitialized();

    drawerApi.drawerLoading(false);
  },
});

const levelFieldMap: Record<number, { codeField: string; nameField: string }> =
  {
    0: { codeField: 'countryCode', nameField: 'countryName' },
    1: { codeField: 'provinceCode', nameField: 'provinceName' },
    2: { codeField: 'cityCode', nameField: 'cityName' },
    3: { codeField: 'districtCode', nameField: 'districtName' },
    5: { codeField: 'townCode', nameField: 'townName' },
    6: { codeField: 'villageCode', nameField: 'villageName' },
  };

/**
 * 将区域信息填入对应字段中（如 districtCode/districtName、cityCode/cityName 等）
 * @param region 要赋值的目标region对象（如编辑表单绑定的 model）
 * @param parentRegion 当前 region 的上级区域（用于设置上级字段）
 */
function fillRegionNameCodeInfo(
  region: Record<string, any>,
  parentRegion?: Region,
) {
  const current = levelFieldMap[region.level];
  if (current) {
    region[current.codeField] = region.code;
    region[current.nameField] = region.name;
  }

  if (parentRegion) {
    const parent = levelFieldMap[parentRegion.level];
    if (parent) {
      region[parent.codeField] = parentRegion.code;
      region[parent.nameField] = parentRegion.name;
    }
  }
}

async function handleConfirm() {
  try {
    drawerApi.lock(true);
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
    }
    const data = cloneDeep(await formApi.getValues());
    let parentCode = data.parentCode;
    let currLevel = data.level;
    while (parentCode && parentCode !== '0' && currLevel > -1) {
      const parentRegion = await regionInfo(parentCode);
      fillRegionNameCodeInfo(data, parentRegion);
      parentCode = parentRegion.parentCode;
      currLevel--;
      console.log('regionInfo：', parentRegion);
    }
    data.ancestors = [
      // level
      data.countryCode, // 0
      data.provinceCode, // 1
      data.cityCode, // 2
      data.districtCode, // 3
      data.townCode, // 4
      data.villageCode, // 5
    ]
      .filter((code, index) => !!code && index !== data.level)
      .join(',');
    console.log('表单数据：', data);
    await (isUpdate.value ? regionUpdate(data) : regionAdd(data));
    resetInitialized();
    emit('reload');
    drawerApi.close();
  } catch (error) {
    console.error(error);
  } finally {
    drawerApi.lock(false);
  }
}

async function handleClosed() {
  await formApi.resetForm();
  resetInitialized();
}
</script>

<template>
  <BasicDrawer :title="title" class="w-[600px]">
    <BasicForm />
  </BasicDrawer>
</template>
